package org.jeecg.modules.system.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.enums.SysAuthType;
import org.jeecg.common.constant.enums.SysLogOperateType;
import org.jeecg.common.constant.enums.SysLogType;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysUserCacheInfo;
import org.jeecg.common.util.IPUtils;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.IscConfig;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysDepartRole;
import org.jeecg.modules.system.entity.SysDepartRoleUser;
import org.jeecg.modules.system.entity.SysRole;
import org.jeecg.modules.system.entity.SysRolePermission;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.entity.SysUserRole;
import org.jeecg.modules.system.mapper.SysDepartMapper;
import org.jeecg.modules.system.mapper.SysDepartRoleMapper;
import org.jeecg.modules.system.mapper.SysDepartRoleUserMapper;
import org.jeecg.modules.system.mapper.SysPermissionMapper;
import org.jeecg.modules.system.mapper.SysRoleMapper;
import org.jeecg.modules.system.mapper.SysUserDepartMapper;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.jeecg.modules.system.mapper.SysUserRoleMapper;
import org.jeecg.modules.system.model.SysLoginModel;
import org.jeecg.modules.system.model.SysUserSysDepartModel;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.system.service.ISysRolePermissionService;
import org.jeecg.modules.system.service.ISysRoleService;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.jeecg.modules.system.service.IUserService;
import org.jeecg.modules.system.util.IscUtil;
import org.jeecg.modules.system.vo.SysUserDepVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sgcc.isc.core.orm.identity.User;
import com.sgcc.isc.core.orm.resource.Function;
import com.sgcc.isc.core.orm.role.OrganizationalRole;
import com.sgcc.isc.core.orm.role.Role;
import com.sgcc.isc.service.adapter.factory.AdapterFactory;
import com.sgcc.isc.service.adapter.helper.IDomainService;
import com.sgcc.isc.service.adapter.helper.IIdentityService;
import com.sgcc.isc.service.adapter.helper.IResourceService;
import com.sgcc.isc.service.adapter.helper.IRoleService;
import com.sgcc.isc.service.adapter.utils.CASTicket;

import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 用户表 isc服务实现类
 * </p>
 *
 * @Author: scott
 * @Date: 2018-12-20
 */
@Service
@Slf4j
@ConditionalOnProperty(name = "mesh.login.auth-impl", havingValue = "isc")
public class IscUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements IUserService {

	@Autowired
	private SysUserMapper userMapper;
	@Autowired
	private SysPermissionMapper sysPermissionMapper;
	@Autowired
	private SysUserRoleMapper sysUserRoleMapper;
	@Autowired
	private SysUserDepartMapper sysUserDepartMapper;
	@Autowired
	private ISysBaseAPI sysBaseAPI;
	@Autowired
	private SysDepartMapper sysDepartMapper;
	@Autowired
	private SysRoleMapper sysRoleMapper;
	@Autowired
	private SysDepartRoleUserMapper departRoleUserMapper;
	@Autowired
	private SysDepartRoleMapper sysDepartRoleMapper;
	@Autowired
	private RedisUtil redisUtil;
	@Autowired
	private ISysDepartService sysDepartService;
	@Autowired
	private ISysDictService sysDictService;
	@Autowired
	private ISysRoleService sysRoleService;
	@Autowired
	private ISysUserRoleService sysUserRoleService;
	@Autowired
	private ISysRolePermissionService sysRolePermissionService;

	@Override
	public Result<JSONObject> login(HttpServletRequest request, HttpServletResponse response, SysLoginModel sysLoginModel) {
		log.info("IscUserServiceImpl 登录方式");
		Result<JSONObject> result = new Result<>();
		String username = sysLoginModel.getUsername();
		String password = sysLoginModel.getPassword();
		// update-begin--Author:scott Date:20190805 for：暂时注释掉密码加密逻辑，有点问题
		// 前端密码加密，后端进行密码解密
		// password =
		// AesEncryptUtil.desEncrypt(sysLoginModel.getPassword().replaceAll("%2B",
		// "\\+")).trim();//密码解密
		// update-begin--Author:scott Date:20190805 for：暂时注释掉密码加密逻辑，有点问题

		// update-begin-author:taoyan date:20190828 for:校验验证码

		/**
		 * String captcha = sysLoginModel.getCaptcha(); if(captcha==null){
		 * result.error500("验证码无效"); return result; }
		 * 
		 * 
		 * String lowerCaseCaptcha = captcha.toLowerCase(); String realKey =
		 * MD5Util.MD5Encode(lowerCaseCaptcha+sysLoginModel.getCheckKey(),
		 * "utf-8"); Object checkCode = redisUtil.get(realKey);
		 * if(checkCode==null || !checkCode.equals(lowerCaseCaptcha)) {
		 * result.error500("验证码错误"); return result; }
		 **/

		// 1.在isc尝试进行用户登录，并获取用户信息
		User user = iscLogin(username, password);

		// 2.在本地数据库进行查找校验
		SysUser sysUser = maintainSysUser(user, result);
		if (!result.isSuccess()) {
			return result;
		}

		// 3.维护role表
		List<SysRole> sysRoles = maintainSysRole(sysUser);

		// 4.维护用户-角色表
		maintainSysUserRole(sysRoles, sysUser.getId());

		// 5.维护角色-功能表
		maintainSysRolePermission(sysRoles);

		sysBaseAPI.addLog("用户名: " + username + ",登录成功！", SysLogType.LOGIN, SysLogOperateType.LOGIN, sysUser.getId());

		// 3.用户登录信息
		userInfo(sysUser, result);
		return result;
	}

	@Override
	public List<SysRole> maintainSysRole(SysUser sysUser) {
		// 获取用户拥有的sysRole
		List<SysRole> sysRoles = getRoles(sysUser.getId());
		// 从数据中批量获取sysRole
		List<SysRole> dbSysRoles = sysRoleMapper.selectBatchIds(sysRoles.stream().map(SysRole::getId).collect(Collectors.toList()));
		// 找出数据库中不存在或者不同的在isc获取的role,更新或保存
		List<SysRole> auSysRoles = sysRoles.stream().filter(s -> !dbSysRoles.contains(s)).collect(Collectors.toList());
		sysRoleService.saveOrUpdateBatch(auSysRoles);
		return sysRoles;
	}

	private List<SysRole> getRoles(String userId) {
		IDomainService domainService = AdapterFactory.getDomainService();
		IRoleService roleService = AdapterFactory.getRoleService();
		// 从isc获取用户拥有的业务角色role
		Set<Role> roles = new HashSet<>();

		List<OrganizationalRole> orgRoles = null;
		try {
			orgRoles = roleService.getOrgRolesByUserId(userId, IscConfig.getIscAppId(), null);
		} catch (Exception e) {
			e.printStackTrace();
			throw new JeecgBootException("同步信息失败");
		}
		if (orgRoles.size() == 0) {
			throw new JeecgBootException("用户在该业务下没有对应的用户组织角色");
		}
		for (OrganizationalRole orgRole : orgRoles) {
			try {
				roles.addAll(roleService.getRoleByRoleId(orgRole.getRoleId()));
			} catch (Exception e) {
				e.printStackTrace();
				throw new JeecgBootException("同步信息失败");
			}
		}
		// role转化成sysRole
		return roles.stream().map(IscUtil::iscRoleToSysRole).collect(Collectors.toList());
	}

	@Override
	public SysUser maintainSysUser(User user, Result<?> result) {
		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(SysUser::getUsername, user.getUserName());
		SysUser sysUser = this.getOne(queryWrapper);
		// 情况1：根据用户信息查询，本地数据库不存在该用户,从isc同步过去
		if (sysUser == null) {
			sysUser = new SysUser();
			IscUtil.iscUserToSysUser(sysUser, user);
			try {
				this.save(sysUser);
			} catch (Exception e) {
				sysBaseAPI.addLog("出错，用户已注销", CommonConstant.OPERATE_TYPE_ADD, null);
				throw new JeecgBootException("用户已注销");
			}
		}
		// 情况2：存在该用户，则更新本地数据库信息
		else {
			IscUtil.iscUserToSysUser(sysUser, user);
			LambdaUpdateWrapper<SysUser> updateWrapper = new UpdateWrapper().lambda();
			updateWrapper.eq(SysUser::getId, user.getId());
			this.update(sysUser, updateWrapper);
			sysUser = this.getOne(queryWrapper);
			checkUserStatus(sysUser, result);

		}
		return sysUser;
	}

	private User iscLogin(String username, String password) {
		IIdentityService iIdentityService = AdapterFactory.getIdentityService();
		CASTicket ticket = IscUtil.getCASTicket(username, password, IscConfig.getServerName());
		// 设置登录状态
		boolean loginStatus = true;
		if (ticket.getTicketGrantingTicket() == null) {
			// TODO: 2020/11/19 暂时取消限制多个登录
			// loginStatus=false;
		}
		try {
			User user = iIdentityService.userLoginAuth(username, password);
			// 登录出现未知错误,但又能获取用户，抛出异常
			if (!loginStatus) {
				Result<Object> result = new Result<>();
				checkUserStatus(IscUtil.iscUserToSysUser(user), result);
				if (!result.isSuccess()) {
					throw new JeecgBootException(result.getMessage());
				}
				throw new JeecgBootException("登录失败");
			}
			user.setPassword(password);

			return user;
		} catch (Exception e) {
			sysBaseAPI.addLog(e.getMessage() + "，用户名:" + username, CommonConstant.LOG_TYPE_LOGIN, null);
			String message = e.getMessage();
			// 如果帐号不存在
			if (IscUtil.isUserNotExist(message, username)) {
				SysUser sysUser = this.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
				// 如果用户存在如果且没有在数据库中被逻辑删除
				if (sysUser != null) {
					// TODO: 2020/11/19 暂时注释逻辑删除用户
					// 逻辑删除用户
					// this.removeById(sysUser.getId());
				}
				throw new JeecgBootException("账号不存在");
			}
			if (IscUtil.isPwdIncorrect(message)) {
				throw new JeecgBootException("密码不正确");
			}
			throw new JeecgBootException(e instanceof JeecgBootException ? e.getMessage() : "登录失败");

		}
	}

	@Override
	public void maintainSysRolePermission(List<SysRole> sysRoles) {
		IResourceService resourceService = AdapterFactory.getResourceService();
		Result<JSONObject> result = new Result<>();
		String ip = "";
		try {
			// 获取request
			HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
			// 获取IP地址
			ip = IPUtils.getIpAddr(request);
		} catch (Exception e) {
			ip = "127.0.0.1";
		}
		try {
			Set<SysRolePermission> suSysRolePerms = new HashSet<>();
			List<String> dSysRolePermIds = new ArrayList<>();
			// 通过获取isc中每个业务角色拥有的功能，找出数据库中需要更新的role-perm数据
			for (SysRole sysRole : sysRoles) {
				List<Function> functions = resourceService.getFuncsByRoleId(sysRole.getId(), null, null);
				LambdaQueryWrapper<SysRolePermission> wrapper = new LambdaQueryWrapper<>();
				wrapper.eq(SysRolePermission::getRoleId, sysRole.getId());
				List<SysRolePermission> sysRolePerms = sysRolePermissionService.list(wrapper);
				List<String> sysRolePermPermIds = sysRolePerms.stream().map(SysRolePermission::getPermissionId).collect(Collectors.toList());
				for (Function function : functions) {
					if (!sysRolePermPermIds.contains(function.getId())) {
						SysRolePermission srp = new SysRolePermission();
						srp.setId(UUIDGenerator.generate());
						srp.setPermissionId(function.getId());
						srp.setRoleId(sysRole.getId());
						srp.setOperateDate(new Date());
						// TODO: 2020/11/5 dataRuleIds
						srp.setOperateIp(ip);
						suSysRolePerms.add(srp);
					}
				}
				// 获取数据库中与isc数据不一致的字段ids
				List<String> functionIds = functions.stream().map(Function::getId).collect(Collectors.toList());
				dSysRolePermIds.addAll(sysRolePerms.stream().filter(s -> !functionIds.contains(s.getPermissionId())).map(SysRolePermission::getId).collect(Collectors.toList()));
			}
			sysRolePermissionService.saveBatch(suSysRolePerms);
			// 删除数据库中多余条目
			sysRolePermissionService.removeByIds(dSysRolePermIds);
		} catch (Exception e) {
			throw new JeecgBootException("同步信息失败");
		}
	}

	@Override
	public void maintainSysUserRole(List<SysRole> sysRoles, String userId) {
		LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(SysUserRole::getUserId, userId);
		List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(wrapper);
		List<String> sysUserRoleRoleIds = sysUserRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
		List<SysUserRole> suSysUserRoles = new ArrayList<>();
		// 选出数据库中不存在的用户-角色对应条目
		for (SysRole sysRole : sysRoles) {
			if (!sysUserRoleRoleIds.contains(sysRole.getId())) {
				SysUserRole t = new SysUserRole();
				t.setId(UUIDGenerator.generate());
				t.setRoleId(sysRole.getId());
				t.setUserId(userId);
				suSysUserRoles.add(t);
			}
		}
		sysUserRoleService.saveOrUpdateBatch(suSysUserRoles);

		// 如果数据表中存在sysRole中不存在的user-role条目，删除
		List<String> sysRoleIds = sysRoles.stream().map(SysRole::getId).collect(Collectors.toList());
		List<String> dSysUserRoleIds = sysUserRoles.stream().filter(s -> !sysRoleIds.contains(s.getRoleId())).map(SysUserRole::getId).collect(Collectors.toList());
		sysUserRoleService.removeByIds(dSysUserRoleIds);
	}

	@Override
	@CacheEvict(value = { CacheConstant.SYS_USERS_CACHE }, allEntries = true)
	public Result<?> resetPassword(String username, String oldpassword, String newpassword, String confirmpassword) {
		SysUser user = userMapper.getUserByName(username);
		String passwordEncode = PasswordUtil.encrypt(username, oldpassword, user.getSalt());
		if (!user.getPassword().equals(passwordEncode)) {
			return Result.error("旧密码输入错误!");
		}
		if (oConvertUtils.isEmpty(newpassword)) {
			return Result.error("新密码不允许为空!");
		}
		if (!newpassword.equals(confirmpassword)) {
			return Result.error("两次输入密码不一致!");
		}
		String password = PasswordUtil.encrypt(username, newpassword, user.getSalt());
		this.userMapper.update(new SysUser().setPassword(password), new LambdaQueryWrapper<SysUser>().eq(SysUser::getId, user.getId()));
		return Result.ok("密码重置成功!");
	}

	@Override
	@CacheEvict(value = { CacheConstant.SYS_USERS_CACHE }, allEntries = true)
	public Result<?> changePassword(SysUser sysUser) {
		String salt = oConvertUtils.randomGen(8);
		sysUser.setSalt(salt);
		String password = sysUser.getPassword();
		String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
		sysUser.setPassword(passwordEncode);
		this.userMapper.updateById(sysUser);
		return Result.ok("密码修改成功!");
	}

	@Override
	@CacheEvict(value = { CacheConstant.SYS_USERS_CACHE }, allEntries = true)
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteUser(String userId) {
		// 1.删除用户
		this.removeById(userId);
		return false;
	}

	@Override
	@CacheEvict(value = { CacheConstant.SYS_USERS_CACHE }, allEntries = true)
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteBatchUsers(String userIds) {
		// 1.删除用户
		this.removeByIds(Arrays.asList(userIds.split(",")));
		return false;
	}

	@Override
	public SysUser getUserByName(String username) {
		return userMapper.getUserByName(username);
	}

	@Override
	@Transactional
	public void addUserWithRole(SysUser user, String roles) {
		this.save(user);
		if (oConvertUtils.isNotEmpty(roles)) {
			String[] arr = roles.split(",");
			for (String roleId : arr) {
				SysUserRole userRole = new SysUserRole(user.getId(), roleId);
				sysUserRoleMapper.insert(userRole);
			}
		}
	}

	@Override
	@CacheEvict(value = { CacheConstant.SYS_USERS_CACHE }, allEntries = true)
	@Transactional
	public void editUserWithRole(SysUser user, String roles) {
		this.updateById(user);
		// 先删后加
		sysUserRoleMapper.delete(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, user.getId()));
		if (oConvertUtils.isNotEmpty(roles)) {
			String[] arr = roles.split(",");
			for (String roleId : arr) {
				SysUserRole userRole = new SysUserRole(user.getId(), roleId);
				sysUserRoleMapper.insert(userRole);
			}
		}
	}

	@Override
	public List<String> getRole(String username) {
		return sysUserRoleMapper.getRoleByUserName(username);
	}

	/**
	 * 通过用户名获取用户角色集合
	 *
	 * @param username
	 *            用户名
	 * @return 角色集合
	 */
	@Override
	public Set<String> getUserRolesSet(String username) {
		// 查询用户拥有的角色集合
		SysUser sysUser = this.getUserByName(username);
		List<SysRole> sysRoles = getRoles(sysUser.getId());
		return sysRoles.stream().map(SysRole::getRoleCode).collect(Collectors.toSet());
	}

	/**
	 * 通过用户名获取用户权限集合
	 *
	 * @param username
	 *            用户名
	 * @return 权限集合
	 */
	@Override
	public Set<String> getUserPermissionsSet(String username) {
		// IResourceService resourceService =
		// AdapterFactory.getResourceService();
		// try {
		// // 用户-》角色-》权限
		// SysUser sysUser = this.getUserByName(username);
		// List<SysRole> sysRoles = getRoles(sysUser.getId());
		// List<SysPermission> permissionList = new ArrayList<>();
		// for (SysRole sysRole : sysRoles) {
		// List<Function> functions =
		// resourceService.getFuncsByRoleId(sysRole.getId(), null, null);
		// for (Function function : functions) {
		// permissionList.add(IscUtil.iscFunctionToSysPermission(function));
		// }
		// }
		// return permissionList.stream().filter(p ->
		// oConvertUtils.isNotEmpty(p.getPerms())).map(SysPermission::getPerms).collect(Collectors.toSet());
		// } catch (Exception e) {
		// throw new JeecgBootException("获取权限出错");
		// }
		return null;
	}

	@Override
	public SysUserCacheInfo getCacheUser(String username) {
		SysUserCacheInfo info = new SysUserCacheInfo();
		info.setOneDepart(true);
		// SysUser user = userMapper.getUserByName(username);
		// info.setSysUserCode(user.getUsername());
		// info.setSysUserName(user.getRealname());

		LoginUser user = sysBaseAPI.getUserByName(username);
		if (user != null) {
			info.setSysUserCode(user.getUsername());
			info.setSysUserName(user.getRealname());
			info.setSysOrgCode(user.getOrgCode());
		}

		// 多部门支持in查询
		List<SysDepart> list = sysDepartMapper.queryUserDeparts(user.getId());
		List<String> sysMultiOrgCode = new ArrayList<String>();
		if (list == null || list.size() == 0) {
			// 当前用户无部门
			// sysMultiOrgCode.add("0");
		} else if (list.size() == 1) {
			sysMultiOrgCode.add(list.get(0).getOrgCode());
		} else {
			info.setOneDepart(false);
			for (SysDepart dpt : list) {
				sysMultiOrgCode.add(dpt.getOrgCode());
			}
		}
		info.setSysMultiOrgCode(sysMultiOrgCode);

		return info;
	}

	// 根据部门Id查询
	@Override
	public IPage<SysUser> getUserByDepId(Page<SysUser> page, String departId, String username) {
		return userMapper.getUserByDepId(page, departId, username);
	}

	@Override
	public IPage<SysUser> getUserByDepIds(Page<SysUser> page, List<String> departIds, String username) {
		return userMapper.getUserByDepIds(page, departIds, username);
	}

	@Override
	public Map<String, String> getDepNamesByUserIds(List<String> userIds) {
		List<SysUserDepVo> list = this.baseMapper.getDepNamesByUserIds(userIds);

		Map<String, String> res = new HashMap<String, String>();
		list.forEach(item -> {
			if (res.get(item.getUserId()) == null) {
				res.put(item.getUserId(), item.getDepartName());
			} else {
				res.put(item.getUserId(), res.get(item.getUserId()) + "," + item.getDepartName());
			}
		});
		return res;
	}

	@Override
	public IPage<SysUser> getUserByDepartIdAndQueryWrapper(Page<SysUser> page, String departId, QueryWrapper<SysUser> queryWrapper) {
		LambdaQueryWrapper<SysUser> lambdaQueryWrapper = queryWrapper.lambda();

		lambdaQueryWrapper.eq(SysUser::getDelFlag, "0");
		lambdaQueryWrapper.inSql(SysUser::getId, "SELECT user_id FROM sys_user_depart WHERE dep_id = '" + departId + "'");

		return userMapper.selectPage(page, lambdaQueryWrapper);
	}

	@Override
	public IPage<SysUserSysDepartModel> queryUserByOrgCode(String orgCode, SysUser userParams, IPage page) {
		List<SysUserSysDepartModel> list = baseMapper.getUserByOrgCode(page, orgCode, userParams);
		Integer total = baseMapper.getUserByOrgCodeTotal(orgCode, userParams);

		IPage<SysUserSysDepartModel> result = new Page<>(page.getCurrent(), page.getSize(), total);
		result.setRecords(list);

		return result;
	}

	// 根据角色Id查询
	@Override
	public IPage<SysUser> getUserByRoleId(Page<SysUser> page, String roleId, String username) {
		return userMapper.getUserByRoleId(page, roleId, username);
	}

	@Override
	@CacheEvict(value = { CacheConstant.SYS_USERS_CACHE }, key = "#username")
	public void updateUserDepart(String username, String orgCode) {
		baseMapper.updateUserDepart(username, orgCode);
	}

	@Override
	public SysUser getUserByPhone(String phone) {
		return userMapper.getUserByPhone(phone);
	}

	@Override
	public SysUser getUserByEmail(String email) {
		return userMapper.getUserByEmail(email);
	}

	@Override
	@Transactional
	public void addUserWithDepart(SysUser user, String selectedParts) {
		// this.save(user); //保存角色的时候已经添加过一次了
		if (oConvertUtils.isNotEmpty(selectedParts)) {
			String[] arr = selectedParts.split(",");
			for (String deaprtId : arr) {
				SysUserDepart userDeaprt = new SysUserDepart(user.getId(), deaprtId);
				sysUserDepartMapper.insert(userDeaprt);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(value = { CacheConstant.SYS_USERS_CACHE }, allEntries = true)
	public void editUserWithDepart(SysUser user, String departs) {
		this.updateById(user); // 更新角色的时候已经更新了一次了，可以再跟新一次
		String[] arr = {};
		if (oConvertUtils.isNotEmpty(departs)) {
			arr = departs.split(",");
		}
		// 查询已关联部门
		List<SysUserDepart> userDepartList = sysUserDepartMapper.selectList(new QueryWrapper<SysUserDepart>().lambda().eq(SysUserDepart::getUserId, user.getId()));
		if (userDepartList != null && userDepartList.size() > 0) {
			for (SysUserDepart depart : userDepartList) {
				// 修改已关联部门删除部门用户角色关系
				if (!Arrays.asList(arr).contains(depart.getDepId())) {
					List<SysDepartRole> sysDepartRoleList = sysDepartRoleMapper.selectList(new QueryWrapper<SysDepartRole>().lambda().eq(SysDepartRole::getDepartId, depart.getDepId()));
					List<String> roleIds = sysDepartRoleList.stream().map(SysDepartRole::getId).collect(Collectors.toList());
					if (roleIds != null && roleIds.size() > 0) {
						departRoleUserMapper.delete(new QueryWrapper<SysDepartRoleUser>().lambda().eq(SysDepartRoleUser::getUserId, user.getId()).in(SysDepartRoleUser::getDroleId, roleIds));
					}
				}
			}
		}
		// 先删后加
		sysUserDepartMapper.delete(new QueryWrapper<SysUserDepart>().lambda().eq(SysUserDepart::getUserId, user.getId()));
		if (oConvertUtils.isNotEmpty(departs)) {
			for (String departId : arr) {
				SysUserDepart userDepart = new SysUserDepart(user.getId(), departId);
				sysUserDepartMapper.insert(userDepart);
			}
		}
	}

	@Override
	public List<SysUser> queryLogicDeleted() {
		return this.queryLogicDeleted(null);
	}

	@Override
	public List<SysUser> queryLogicDeleted(LambdaQueryWrapper<SysUser> wrapper) {
		if (wrapper == null) {
			wrapper = new LambdaQueryWrapper<>();
		}
		wrapper.eq(SysUser::getDelFlag, "1");
		return userMapper.selectLogicDeleted(wrapper);
	}

	@Override
	public boolean revertLogicDeleted(List<String> userIds, SysUser updateEntity) {
		String ids = String.format("'%s'", String.join("','", userIds));
		return userMapper.revertLogicDeleted(ids, updateEntity) > 0;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean removeLogicDeleted(List<String> userIds) {
		String ids = String.format("'%s'", String.join("','", userIds));
		// 1. 删除用户
		int line = userMapper.deleteLogicDeleted(ids);
		// 2. 删除用户部门关系
		line += sysUserDepartMapper.delete(new LambdaQueryWrapper<SysUserDepart>().in(SysUserDepart::getUserId, userIds));
		// 3. 删除用户角色关系
		line += sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, userIds));
		return line != 0;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateNullPhoneEmail() {
		userMapper.updateNullByEmptyString("email");
		userMapper.updateNullByEmptyString("phone");
		return true;
	}

	@Override
	public void saveThirdUser(SysUser sysUser) {
		// 保存用户
		String userid = UUIDGenerator.generate();
		sysUser.setId(userid);
		baseMapper.insert(sysUser);
		// 获取第三方角色
		SysRole sysRole = sysRoleMapper.selectOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getRoleCode, "third_role"));
		// 保存用户角色
		SysUserRole userRole = new SysUserRole();
		userRole.setRoleId(sysRole.getId());
		userRole.setUserId(userid);
		sysUserRoleMapper.insert(userRole);
	}

	@Override
	public List<SysUser> queryByDepIds(List<String> departIds, String username) {
		return userMapper.queryByDepIds(departIds, username);
	}

	@Override
	public Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result) {
		String syspassword = sysUser.getPassword();
		String username = sysUser.getUsername();
		// 生成token
		String token = JwtUtil.sign(username, syspassword);
		// 设置token缓存有效时间
		redisUtil.set(CommonConstant.PREFIX_USER_TOKEN +username+"_"+token, token);
		redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN +username+"_"+token, JwtUtil.EXPIRE_TIME * 2 / 1000);

		JSONObject obj = new JSONObject();
		List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
		obj.put("departs", departs);
		if (departs == null || departs.size() == 0) {
			obj.put("multi_depart", 0);
		} else if (departs.size() == 1) {
			this.updateUserDepart(username, departs.get(0).getOrgCode());
			obj.put("multi_depart", 1);
		} else {
			obj.put("multi_depart", 2);
		}
		obj.put("token", token);
		obj.put("userInfo", sysUser);
		obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
		result.setResult(obj);
		result.success("登录成功");
		return result;
	}

	@Override
	public Result<JSONObject> logout(LoginUser loginUser) {
		log.info("ISC logout start-user:" + loginUser.getUsername());

		HttpClient client = null;
		PostMethod logouPost = null;
		PostMethod timeoutPost = null;
		// PostMethod destorySession = null;
		String server = IscConfig.getIscSsoPath(); // isc_sso登录服务
		String service = IscConfig.getServerName(); // 业务系统访问地址，与节点信息维护中的服务URL一致

		String userName = loginUser.getUsername();
		try {

			if (StringUtils.isNotBlank(loginUser.getThirdId())) {
				client = new HttpClient();

				// 注销会话票据及记录注销日志
				logouPost = new PostMethod(server + "/logout");//
				logouPost.setRequestBody(new NameValuePair[] { new NameValuePair("service", service), new NameValuePair("username", userName), new NameValuePair("iscUserId", loginUser.getThirdId()) });
				log.info(String.format("logouPost param  service:%s,username:%s,iscUserId:%s", service, userName, loginUser.getThirdId()));

				// 销毁缓存会话数据
				timeoutPost = new PostMethod(server + "/timeout");//
				timeoutPost.setRequestBody(new NameValuePair[] { new NameValuePair("userId", loginUser.getThirdId()) });
				log.info(String.format("timeoutPost param  userId:%s", loginUser.getThirdId()));

				// 下线用户，isc_user_login表在线记录更新
				// destorySession = new PostMethod(server + "/destorySession");
				// destorySession.setRequestBody(new NameValuePair[] { new
				// NameValuePair("userId", loginUser.getThirdId()) });

				client.executeMethod(logouPost);
				client.executeMethod(timeoutPost);
				// client.executeMethod(destorySession);

				// 打出响应结果
				String response = logouPost.getResponseBodyAsString();
				log.info("logouPost HttpCode:" + logouPost.getStatusCode());
				log.info(response);

				log.info("===================================");
				String response2 = timeoutPost.getResponseBodyAsString();
				log.info("timeoutPost HttpCode:" + timeoutPost.getStatusCode());
				log.info(response2);
			} else {
				log.error("iscSSOUserBean is null, username:" + userName);
				throw new JeecgBootException("get isc user is null");
			}
		} catch (Exception e) {
			log.error("ISC logout error", e);
			throw new JeecgBootException(e.getMessage());
		} finally {
			if (logouPost != null) {
				logouPost.releaseConnection();
			}

			if (timeoutPost != null) {
				timeoutPost.releaseConnection();
			}
			// destorySession.releaseConnection();
		}
		log.info("ISC logout sucess-user:" + loginUser.getUsername());
		return null;
	}

	@Override
	public Result checkUserIsEffective(SysUser sysUser) {
		Result<?> result = new Result<Object>();
		// 情况1：根据用户信息查询，该用户不存在
		if (sysUser == null) {
			result.error500("该用户不存在，请注册");
			sysBaseAPI.addLog("用户登录失败，用户不存在！", CommonConstant.LOG_TYPE_LOGIN, null);
			return result;
		}
		checkUserStatus(sysUser, result);
		return result;
	}

	/**
	 * 检查用户状态
	 *
	 * @param sysUser
	 * @param result
	 */
	public void checkUserStatus(SysUser sysUser, Result<?> result) {
		// 情况4：根据用户信息查询，该用户已禁用
		if (CommonConstant.USER_FREEZE.equals(sysUser.getStatus())) {
			sysBaseAPI.addLog("用户登录失败，用户名:" + sysUser.getUsername() + "已禁用！", CommonConstant.LOG_TYPE_LOGIN, null);
			result.error500("该用户已禁用");
			return;
		}
		// 用户密码已过期
		if (CommonConstant.PASSWORD_EXPIRED.equals(sysUser.getStatus())) {
			sysBaseAPI.addLog("用户登录失败，用户名:" + sysUser.getUsername() + "密码已过期！", CommonConstant.LOG_TYPE_LOGIN, null);
			result.error500("该用户密码已过期");
			return;
		}
		// 用户已过期
		if (CommonConstant.USER_EXPIRED.equals(sysUser.getStatus())) {
			sysBaseAPI.addLog("用户登录失败，用户名:" + sysUser.getUsername() + "用户已过期！", CommonConstant.LOG_TYPE_LOGIN, null);
			result.error500("该用户已过期");
		}
	}

	@Override
	public SysUser syncUser(String userId, String username) {
		SysUser sysUser = new SysUser();
		sysUser.setId(userId);
		sysUser.setDelFlag(0);
		sysUser.setStatus(1);
		sysUser.setUsername(username);
		sysUser.setRealname(username);
		String salt = oConvertUtils.randomGen(8);
		sysUser.setSalt(salt);
		sysUser.setPassword("1234567");
		String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), sysUser.getPassword(), salt);
		sysUser.setPassword(passwordEncode);

		sysUser.setThirdId(userId);
		sysUser.setThirdType(SysAuthType.ISC.getName());

		sysUser.setCreateTime(new Date());
		try {
			log.info("----save---user");
			save(sysUser);
			// 3.维护role表
			log.info("----save---role");
			List<SysRole> sysRoles = maintainSysRole(sysUser);

			// 4.维护用户-角色表
			log.info("----save---role");
			maintainSysUserRole(sysRoles, sysUser.getId());

			// 5.维护角色-功能表
			log.info("----save---funtion");
			maintainSysRolePermission(sysRoles);

		} catch (Exception e) {
			log.error("----syncUser", e);
			throw new JeecgBootException("用户已注销");
		}
		return sysUser;
	}
}
